#include "app_buff.h"
#include "log/log.h"
#include "stdlib.h"
#include "string.h"

//初始化子缓冲区
static SubBuffer *init_sub_buffer(int total_size)
{
    //申请自缓冲区的内存
    SubBuffer *sub_buffer = (SubBuffer *)malloc(sizeof(SubBuffer));
    sub_buffer->ptr  = malloc(total_size);//申请子缓冲区内存
    sub_buffer->total_size = total_size;//设置子缓冲区大小
    sub_buffer->len = 0;//设置子缓冲区长度
    return sub_buffer;//返回子缓冲区

}
//初始化缓冲区
Buffer *app_buffer_init(int total_size)
{
    //初始化缓冲区
    Buffer *buffer = (Buffer *)malloc(sizeof(Buffer));
    //初始化子缓冲区
    buffer->sub_buffers[0] = init_sub_buffer(total_size);
    buffer->sub_buffers[1] = init_sub_buffer(total_size);
    //设置读写索引
    buffer->read_index = 0;
    buffer->write_index = 1;
    //初始化读写锁
    pthread_mutex_init(&buffer->write_lock, NULL);
    pthread_mutex_init(&buffer->read_lock, NULL);
    return buffer;//返回缓冲区
}
 //释放缓冲区
void app_buffer_free(Buffer *buffer)
{
    //释放子缓冲区ptr
    free(buffer->sub_buffers[0]->ptr);
    free(buffer->sub_buffers[1]->ptr);
    //释放子缓冲区
    free(buffer->sub_buffers[0]);
    free(buffer->sub_buffers[1]);
    //释放读写锁
    pthread_mutex_destroy(&buffer->write_lock);
    pthread_mutex_destroy(&buffer->read_lock);
    //释放缓冲区
    free(buffer);
}
//切换子缓冲区
static void switch_sub_buffer(Buffer *buffer)
{
    log_debug("准备切换子缓冲区，加写锁");
    pthread_mutex_lock(&buffer->write_lock);//写的过程中不能切换
    //根冒泡很像
    int temp_index = buffer->read_index;
    buffer->read_index = buffer->write_index;
    buffer->write_index = temp_index;
    log_debug("切换子缓冲区，解锁");
    pthread_mutex_unlock(&buffer->write_lock);

}
//向缓冲区写入数据
int app_buffer_write(Buffer *buffer, char *data, int len)
{
    //数据一般不会超过一个字节的大小255bit
    if (len > 255)
    {
        log_error("一次缓存的数据长度不能超过255个bit");
        return -1;
    }
    log_debug("准备写入数据，加写锁");
    pthread_mutex_lock(&buffer->write_lock);
    //获取到写缓冲区
    SubBuffer *w_buffer = buffer->sub_buffers[buffer->write_index];
    //判断缓冲区是否写满
    if (len + 1 > w_buffer->total_size - w_buffer->len)
    {
        log_error("写缓冲区的剩余空间不足");
        pthread_mutex_unlock(&buffer->write_lock);//解锁
        return -1;
    }
    
    //写入data数据的长度len（用一个字节）
    w_buffer->ptr[w_buffer->len] = len;
    //写入data数据
    memcpy(w_buffer->ptr + w_buffer->len + 1, data, len);
    //更新写缓冲区长度len
      w_buffer->len += len + 1;
    log_debug("写入数据，解锁");
    pthread_mutex_unlock(&buffer->write_lock);//解锁
return 0;
}
//从缓冲区读取数据
int app_buffer_read(Buffer *buffer, char *data_buf, int buf_len)
{
    log_debug("准备读取数据，加读锁");
    pthread_mutex_lock(&buffer->read_lock);
    //获取到读缓冲区
    SubBuffer *r_buffer = buffer->sub_buffers[buffer->read_index];
    //判断缓冲区是否有数据
    if (r_buffer->len == 0)
    {
        log_error("读缓冲区没有数据");
        //切换缓冲区
        switch_sub_buffer(buffer);
        //获取到读缓冲区
        r_buffer = buffer->sub_buffers[buffer->read_index];
        //判断缓冲区是否有数据
        if (r_buffer->len == 0)
        {
            log_error("读缓冲区没有数据");
            pthread_mutex_unlock(&buffer->read_lock);//解锁
            return -1;
        }
    }
    //先读第一个字节，获取data的长度
    int data_len = r_buffer->ptr[0];
    log_debug("读取数据长度为%d", data_len);
    //判断data_buf的长度是否足够
    if (data_len > buf_len)
    {
        log_error("data_buf的长度不足");
        pthread_mutex_unlock(&buffer->read_lock);//解锁
        return -1;
    }
    //读取后面data_len个字节的数据，存入data_buf
    memcpy(data_buf, r_buffer->ptr + 1, data_len);
    //将后面的数据前移
    memmove(r_buffer->ptr, r_buffer->ptr + 1 + data_len, r_buffer->len - 1 - data_len);
    //更新读缓冲区长度len
    r_buffer->len -= 1 + data_len;
    //如果读取缓冲区为空，切换缓冲区，为下一次读取数据作准备
    if (r_buffer->len == 0)
    {
        log_debug("切换子缓冲区，加锁");
        switch_sub_buffer(buffer);
    }
    log_debug("读取数据，解锁");
    pthread_mutex_unlock(&buffer->read_lock);//解锁
    //返回读取的数据长度data_len
    return data_len;
}